From d352913aeb5efefe56cc4b3df329aedbae0ab2ff Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 15 Jul 2005 08:50:48 +0000 Subject: [PATCH] Enable VMX domains on a SMP dom0. Not all vectors go through do_IRQ(). It's possible to look up the handler in the IDT and call that one, but it'll result in two trap frames. Signed-off-by: Xiaofeng Ling Signed-off-by: Arun Sharma --- xen/arch/x86/vmx.c | 68 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 362cbe0f9d..e4cfb5e4c1 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -1383,6 +1383,53 @@ static inline void vmx_vmexit_do_hlt(void) raise_softirq(SCHEDULE_SOFTIRQ); } +static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs) +{ + unsigned int vector; + int error; + + asmlinkage void do_IRQ(struct cpu_user_regs *); + void smp_apic_timer_interrupt(struct cpu_user_regs *); + void timer_interrupt(int, void *, struct cpu_user_regs *); + void smp_event_check_interrupt(void); + void smp_invalidate_interrupt(void); + void smp_call_function_interrupt(void); + void smp_spurious_interrupt(struct cpu_user_regs *regs); + void smp_error_interrupt(struct cpu_user_regs *regs); + + if ((error = __vmread(VM_EXIT_INTR_INFO, &vector)) + && !(vector & INTR_INFO_VALID_MASK)) + __vmx_bug(regs); + + vector &= 0xff; + local_irq_disable(); + + switch(vector) { + case LOCAL_TIMER_VECTOR: + smp_apic_timer_interrupt(regs); + break; + case EVENT_CHECK_VECTOR: + smp_event_check_interrupt(); + break; + case INVALIDATE_TLB_VECTOR: + smp_invalidate_interrupt(); + break; + case CALL_FUNCTION_VECTOR: + smp_call_function_interrupt(); + break; + case SPURIOUS_APIC_VECTOR: + smp_spurious_interrupt(regs); + break; + case ERROR_APIC_VECTOR: + smp_error_interrupt(regs); + break; + default: + regs->entry_vector = vector; + do_IRQ(regs); + break; + } +} + static inline void vmx_vmexit_do_mwait(void) { #if VMX_DEBUG @@ -1586,27 +1633,8 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) break; } case EXIT_REASON_EXTERNAL_INTERRUPT: - { - extern asmlinkage void do_IRQ(struct cpu_user_regs *); - extern void smp_apic_timer_interrupt(struct cpu_user_regs *); - extern void timer_interrupt(int, void *, struct cpu_user_regs *); - unsigned int vector; - - if ((error = __vmread(VM_EXIT_INTR_INFO, &vector)) - && !(vector & INTR_INFO_VALID_MASK)) - __vmx_bug(®s); - - vector &= 0xff; - local_irq_disable(); - - if (vector == LOCAL_TIMER_VECTOR) { - smp_apic_timer_interrupt(®s); - } else { - regs.entry_vector = vector; - do_IRQ(®s); - } + vmx_vmexit_do_extint(®s); break; - } case EXIT_REASON_PENDING_INTERRUPT: __vmwrite(CPU_BASED_VM_EXEC_CONTROL, MONITOR_CPU_BASED_EXEC_CONTROLS); -- 2.30.2